#ifndef _MCMC_DIFFUSION
#define _MCMC_DIFFUSION

#include "mcRaster.h"
#include "mcRasterColor.h"
#include "mcmcMap.h"
#include "mcRand.h"
#include "mcmcParticle.h"

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
class McStackPositions
{
public:
	McStackPositions();
	virtual void	Empty(void);
	
	virtual void	Insert(const McImagePoint &a);
	virtual bool	IsLoopingAround(const McImagePoint &a);
	
	virtual McImagePoint	PreviousVisit(const int i);

protected:
	SimpleMatrix<McImagePoint>	vc_stack;
	int			head,tail;
	mcmcVector<int>	tocheck;
};


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
class MCMC_Diff_Node
{
public:
	// construction & destruction
	MCMC_Diff_Node();

	// operators
	MCMC_Diff_Node& operator=(const MCMC_Diff_Node &x);
	bool operator==(const MCMC_Diff_Node &x);

public:
	int	index,id_region,id_node;
};


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
class MCMC_Diffusion
{
public:
	// construction & destruction
	MCMC_Diffusion();
	~MCMC_Diffusion();

	// operatrions
	void	Set(MCMC_Map &map, Raster_Color<uchar> &raster, MCMC_Particle *pparticle1);
	void	Go(LinkList<int> &list_regions);
	void	DiffuseRegionBoundary(const int id_region, const bool bResort=false);
	void	MoveNodes(const int id_region);
	void	Competition(const int id_region);
	inline	MCMC_Layer_Regions* LayerRegion(void);

	inline	void	ChangeMapPointer(MCMC_Map &map){pmap=&map;};


	void	GridDiffuseRegionBoundary(const int id_aregion);

	void	GridGo(LinkList<int> &list_regions);

protected:
	bool	DeleteVeryShortCSeg(LinkList<int> *plist_affected_cseg=NULL);
	void	SortRegionNodes(LinkList<int> *plist_region=NULL);
	int		GetSortedIndex(const int id_region,const int id_node);
	void	GetBoundaries(LinkList<int> &list_cseg, const int id_region);
	McPoint2D	NewPosition(const double x_old, const double y_old, McPoint2D &pt_offset);

private:
	bool	VerySmallAngle(const double angle);
	bool	SharpAngle(const double angle);

protected:
	Raster_Color<uchar> *praster;
	MCMC_Map			*pmap;
	Raster<int>			mx_region_label;

	MCMC_Particle		*pparticles;


private:
	LinkList<MCMC_Diff_Node>	*pdiff_nodes;
	int							Size_Diff_Node;
	LinkList<int>				list_old_cseg;
};

inline	MCMC_Layer_Regions* MCMC_Diffusion::LayerRegion(void)

{
	if (pmap == NULL)
		return NULL;
	else
		return pmap->LayerRegion();
}





#endif
